package com.glsc.ngateway.platform.utils.report;

import cn.hutool.core.annotation.Alias;
import cn.hutool.poi.excel.ExcelUtil;
import com.glsc.ngateway.common.api.flowable.dto.demand.DemandManagementExportDto;
import com.glsc.ngateway.platform.domain.Vpn;
import com.glsc.ngateway.platform.dto.FortressNewMachineImportDto;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.Fortress;
import com.glsc.ngateway.common.api.platform.dto.gitee.IssueExportDto;
import com.glsc.ngateway.platform.domain.FortressNew;
import com.glsc.ngateway.common.base.dto.cmdb.*;
import com.glsc.ngateway.common.api.flowable.dto.EventExportDto;
import com.glsc.ngateway.common.api.platform.dto.it.networkassets.RateExceptionExcludeDto;
import com.glsc.ngateway.common.api.platform.dto.other.FortressAccountImportDto;
import com.glsc.ngateway.common.api.platform.dto.other.FortressMachineImportDto;
import com.glsc.ngateway.common.api.platform.dto.vendor.VendorExportDto;
import com.glsc.ngateway.common.api.platform.dto.vendor.VendorImportDto;
import com.glsc.ngateway.platform.dto.UploadIpInfoDetailDto;
import com.glsc.ngateway.platform.dto.UploadReturnAmountDto;
import com.glsc.ngateway.platform.dto.UploadTestCaseDto;
import com.glsc.ngateway.platform.dto.VpnExportDto;
import com.glsc.ngateway.platform.utils.StringUtils;
import io.jsonwebtoken.lang.Collections;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.logging.log4j.util.Strings;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 报表导出配置枚举
 *
 * @author xuchang
 */
@Getter
@AllArgsConstructor
public enum ReportFileConfigEnum {
    /**
     * 云管返回金额数据
     */
    RETURN_AMOUNT(0, 0, "导入资产分摊数据.xlsx", getTitle(UploadReturnAmountDto.class),
            (ExportBuilder<List<UploadReturnAmountDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getItUniqueKey()),
                            StringUtils.getOrEmpty(h.getSectionStartDate()),
                            StringUtils.getOrEmpty(h.getSectionEndDate()),
                            StringUtils.getOrEmpty(h.getServerAmount())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, UploadReturnAmountDto.class)
    ),
    /**
     * 测试用例
     */
    TEST_CASE(0, 0, "测试用例.xlsx", getTitle(UploadTestCaseDto.class),
            (ExportBuilder<List<UploadTestCaseDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getCaseType()),
                            StringUtils.getOrEmpty(h.getCaseDataType()),
                            StringUtils.getOrEmpty(h.getCaseTitle()),
                            StringUtils.getOrEmpty(h.getCaseContent()),
                            StringUtils.getOrEmpty(h.getCaseBeforeCondition()),
                            StringUtils.getOrEmpty(h.getCaseExpectResult()),
                            StringUtils.getOrEmpty(h.getRemark())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, UploadTestCaseDto.class)
    ),
    /**
     * 应用详情分摊明细
     */
    UPLOAD_IPINFO_DETAIL(0, 0, "应用详情分摊明细.xlsx", getTitle(UploadIpInfoDetailDto.class),
            (ExportBuilder<List<UploadIpInfoDetailDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                            StringUtils.getOrEmpty(h.getUniqueKey()),
                            StringUtils.getOrEmpty(h.getIp()),
                            StringUtils.getOrEmpty(h.getVirtualName()),
                            StringUtils.getOrEmpty(h.getSystemName()),
                            StringUtils.getOrEmpty(h.getComponentCategory()),
                            StringUtils.getOrEmpty(h.getComponentName()),
                            StringUtils.getOrEmpty(h.getComponentPath()),
                            StringUtils.getOrEmpty(h.getMainOrBackup()),
                            StringUtils.getOrEmpty(h.getRunStatus()),
                            StringUtils.getOrEmpty(h.getExclusive()),
                            StringUtils.getOrEmpty(h.getSourceAllocation())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, UploadIpInfoDetailDto.class)
    ),
    /**
     * 主机信息
     */
    HOST_INFORMATION_MAINTENANCE(0, 0, "主机信息.xlsx", getTitle(com.glsc.ngateway.common.api.platform.dto.it.networkassets.HostInformationMaintenanceDto.class),
            (ExportBuilder<List<com.glsc.ngateway.common.api.platform.dto.it.networkassets.HostInformationMaintenanceDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getId()),
                    StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getHostname()), StringUtils.getOrEmpty(h.getServiceZone()),
                    StringUtils.getOrEmpty(h.getDeviceRole()), StringUtils.getOrEmpty(h.getSnmpVersion()), StringUtils.getOrEmpty(h.getSnmpRoCommunity()),
                    StringUtils.getOrEmpty(h.getMgmtInterface()), StringUtils.getOrEmpty(h.getUsername()), StringUtils.getOrEmpty(h.getPassword()),
                    StringUtils.getOrEmpty(h.getTaskList()), StringUtils.getOrEmpty(h.getHostid()), StringUtils.getOrEmpty(h.getBindSerialNumList()),
                    StringUtils.getOrEmpty(h.getDeployedModeList())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, com.glsc.ngateway.common.api.platform.dto.it.networkassets.HostInformationMaintenanceDto.class)
    ),
    /**
     * 接口状态
     */
    INTERFACE_STATUS(0, 0, "接口状态.xlsx", getTitle(com.glsc.ngateway.common.api.platform.dto.it.networkassets.InterfaceStatusDto.class),
            (ExportBuilder<List<com.glsc.ngateway.common.api.platform.dto.it.networkassets.InterfaceStatusDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getId()),
                    StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getIfIndex()), StringUtils.getOrEmpty(h.getIfName()),
                    StringUtils.getOrEmpty(h.getIfType()), StringUtils.getOrEmpty(h.getIfHighSpeed()), StringUtils.getOrEmpty(h.getIfOperStatus()),
                    StringUtils.getOrEmpty(h.getIfErrDis())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, com.glsc.ngateway.common.api.platform.dto.it.networkassets.InterfaceStatusDto.class)
    ),
    /**
     * 维保信息
     */
    MAINTENANCE_INFORMATION(0, 0, "维保信息.xlsx", getTitle(com.glsc.ngateway.common.api.platform.dto.it.networkassets.MaintenanceInformationDto.class),
            (ExportBuilder<List<com.glsc.ngateway.common.api.platform.dto.it.networkassets.MaintenanceInformationDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getId()),
                    StringUtils.getOrEmpty(h.getSerialNum()), StringUtils.getOrEmpty(h.getMaintenanceInfo()), StringUtils.getOrEmpty(h.getSupplier()),
                    StringUtils.getOrEmpty(h.getStart()), StringUtils.getOrEmpty(h.getEnd()), StringUtils.getOrEmpty(h.getBindOa())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, com.glsc.ngateway.common.api.platform.dto.it.networkassets.MaintenanceInformationDto.class)
    ),
    /**
     * 网络资产
     */
    NETWORK_ASSET_MAINTENANCE(0, 0, "网络资产.xlsx", getTitle(com.glsc.ngateway.common.api.platform.dto.it.networkassets.NetworkAssetMaintenanceDto.class),
            (ExportBuilder<List<com.glsc.ngateway.common.api.platform.dto.it.networkassets.NetworkAssetMaintenanceDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getId()),
                    StringUtils.getOrEmpty(h.getSerialNum()), StringUtils.getOrEmpty(h.getVendor()), StringUtils.getOrEmpty(h.getModel()),
                    StringUtils.getOrEmpty(h.getOs()), StringUtils.getOrEmpty(h.getVersion()), StringUtils.getOrEmpty(h.getStatus()),
                    StringUtils.getOrEmpty(h.getSite()), StringUtils.getOrEmpty(h.getRack()), StringUtils.getOrEmpty(h.getUnit()),
                    StringUtils.getOrEmpty(h.getManufactureDate()), StringUtils.getOrEmpty(h.getExpiredDate()), StringUtils.getOrEmpty(h.getAssetNUM()),
                    StringUtils.getOrEmpty(h.getContractNUM())))
                    .collect(Collectors.toList()),
            //导入编辑，维保信息暂不处理
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, com.glsc.ngateway.common.api.platform.dto.it.networkassets.NetworkAssetMaintenanceDto.class)
    ),
    /**
     * 速率异常
     */
    RATE_EXP_EXL(0, 0, "速率异常.xlsx", getTitle(com.glsc.ngateway.common.api.platform.dto.it.networkassets.RateExceptionExcludeDto.class),
            (ExportBuilder<List<com.glsc.ngateway.common.api.platform.dto.it.networkassets.RateExceptionExcludeDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getId()),
                    StringUtils.getOrEmpty(h.getHost()), StringUtils.getOrEmpty(h.getIfName()), StringUtils.getOrEmpty(h.getReferenceSpeed()),
                    StringUtils.getOrEmpty(h.getDescription())))
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, com.glsc.ngateway.common.api.platform.dto.it.networkassets.RateExceptionExcludeDto.class)
    ),
    /**
     * 事件流程
     */
    EVENT_FLOW(0, 0, "事件流程.xlsx", getTitle(EventExportDto.class),
            (ExportBuilder<List<EventExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getEventTitle()),
                    StringUtils.getOrEmpty(h.getEventGrade()),
                    StringUtils.getOrEmpty(h.getDetailImproves()),
                    StringUtils.getOrEmpty(h.getSystemName()),
                    StringUtils.getOrEmpty(h.getEventCause()),
                    StringUtils.getOrEmpty(h.getEventClass()),
                    StringUtils.getOrEmpty(h.getEventHappenTime()),
                    StringUtils.getOrEmpty(h.getFlowCreateOperatorName()),
                    StringUtils.getOrEmpty(h.getProcessCreateTime())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, RateExceptionExcludeDto.class)
    ),
    /**
     * cmdb cpu规格
     */
    CMDB_CPU_STANDARD(0, 0, "cpu规格.xlsx", getTitle(CmdbCpuStandardImportDto.class),
            (ExportBuilder<List<CmdbCpuStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCore()),
                    StringUtils.getOrEmpty(h.getSmt())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbCpuStandardImportDto.class)
    ),
    /**
     * cmdb 内存规格
     */
    CMDB_MEMORY_STANDARD(0, 0, "内存规格.xlsx", getTitle(CmdbMemoryStandardImportDto.class),
            (ExportBuilder<List<CmdbMemoryStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCapacity())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbMemoryStandardImportDto.class)
    ),
    /**
     * cmdb 硬盘规格
     */
    CMDB_DISK_STANDARD(0, 0, "硬盘规格.xlsx", getTitle(CmdbDiskStandardImportDto.class),
            (ExportBuilder<List<CmdbDiskStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getDiskType()), StringUtils.getOrEmpty(h.getCapacity()), StringUtils.getOrEmpty(h.getSize())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbDiskStandardImportDto.class)
    ),
    /**
     * cmdb 配件规格
     */
    CMDB_PART_STANDARD(0, 0, "配件规格.xlsx", getTitle(CmdbPartStandardImportDto.class),
            (ExportBuilder<List<CmdbPartStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getAdaptModel()), StringUtils.getOrEmpty(h.getPerformance()),
                    StringUtils.getOrEmpty(h.getChannelAmount()), StringUtils.getOrEmpty(h.getPortType()), StringUtils.getOrEmpty(h.getPartType())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbPartStandardImportDto.class)
    ),
    /**
     * cmdb 设备(服务器)规格
     */
    CMDB_DEVICE_STANDARD(0, 0, "服务器规格.xlsx", getTitle(CmdbDeviceStandardImportDto.class),
            (ExportBuilder<List<CmdbDeviceStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getStandardName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getModel()),
                    StringUtils.getOrEmpty(h.getCpuPartNum()), StringUtils.getOrEmpty(h.getCpuAmount()), StringUtils.getOrEmpty(h.getCpuPortAmount()),
                    StringUtils.getOrEmpty(h.getMemoryPartNum()), StringUtils.getOrEmpty(h.getMemoryAmount()), StringUtils.getOrEmpty(h.getMemoryPortAmount()),
                    StringUtils.getOrEmpty(h.getUAmount()), StringUtils.getOrEmpty(h.getPciPortAmount()), StringUtils.getOrEmpty(h.getElcPortAmount()),
                    StringUtils.getOrEmpty(h.getDiskPortAmount()), StringUtils.getOrEmpty(h.getDiskPartNum1()), StringUtils.getOrEmpty(h.getDiskAmount1()),
                    StringUtils.getOrEmpty(h.getDiskPartNum2()), StringUtils.getOrEmpty(h.getDiskAmount2()), StringUtils.getOrEmpty(h.getDiskCagePartNum()),
                    StringUtils.getOrEmpty(h.getDiskCageAmount()), StringUtils.getOrEmpty(h.getPciCagePartNum()), StringUtils.getOrEmpty(h.getPciCageAmount()),
                    StringUtils.getOrEmpty(h.getArrayCardPartNum()), StringUtils.getOrEmpty(h.getArrayCardAmount()), StringUtils.getOrEmpty(h.getArrayCardCellPartNum()),
                    StringUtils.getOrEmpty(h.getArrayCardCellAmount()), StringUtils.getOrEmpty(h.getNetworkCardPartNum1()), StringUtils.getOrEmpty(h.getNetworkCardAmount1()),
                    StringUtils.getOrEmpty(h.getNetworkCardPartNum2()), StringUtils.getOrEmpty(h.getNetworkCardAmount2()), StringUtils.getOrEmpty(h.getHbaCardPartNum()),
                    StringUtils.getOrEmpty(h.getHbaCardAmount()), StringUtils.getOrEmpty(h.getPowerSourcePartNum()), StringUtils.getOrEmpty(h.getPowerSourceAmount()),
                    StringUtils.getOrEmpty(h.getGpuPartNum()), StringUtils.getOrEmpty(h.getGpuAmount()), StringUtils.getOrEmpty(h.getGpuCagePartNum()),
                    StringUtils.getOrEmpty(h.getGpuCageAmount())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbDeviceStandardImportDto.class)
    ),
    /**
     * cmdb cpu明细
     */
    CMDB_CPU_DETAIL(0, 0, "cpu明细.xlsx", getTitle(CmdbCommonDetailImportDto.class),
            (ExportBuilder<List<CmdbCommonDetailImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getPartNum()), StringUtils.getOrEmpty(h.getSn()), StringUtils.getOrEmpty(h.getManufactDate()),
                    StringUtils.getOrEmpty(h.getExpirateDate()), StringUtils.getOrEmpty(h.getMachineRoom()), StringUtils.getOrEmpty(h.getPurchaseDate())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbCommonDetailImportDto.class)
    ),
    /**
     * cmdb 内存明细
     */
    CMDB_MEMORY_DETAIL(0, 0, "内存明细.xlsx", getTitle(CmdbCommonDetailImportDto.class),
            (ExportBuilder<List<CmdbCommonDetailImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getPartNum()), StringUtils.getOrEmpty(h.getSn()), StringUtils.getOrEmpty(h.getManufactDate()),
                    StringUtils.getOrEmpty(h.getExpirateDate()), StringUtils.getOrEmpty(h.getMachineRoom()), StringUtils.getOrEmpty(h.getPurchaseDate())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbCommonDetailImportDto.class)
    ),
    /**
     * cmdb 硬盘明细
     */
    CMDB_DISK_DETAIL(0, 0, "硬盘明细.xlsx", getTitle(CmdbCommonDetailImportDto.class),
            (ExportBuilder<List<CmdbCommonDetailImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getPartNum()), StringUtils.getOrEmpty(h.getSn()), StringUtils.getOrEmpty(h.getManufactDate()),
                    StringUtils.getOrEmpty(h.getExpirateDate()), StringUtils.getOrEmpty(h.getMachineRoom()), StringUtils.getOrEmpty(h.getPurchaseDate())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbCommonDetailImportDto.class)
    ),
    /**
     * cmdb 配件明细
     */
    CMDB_PART_DETAIL(0, 0, "配件明细.xlsx", getTitle(CmdbCommonDetailImportDto.class),
            (ExportBuilder<List<CmdbCommonDetailImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getPartNum()), StringUtils.getOrEmpty(h.getSn()), StringUtils.getOrEmpty(h.getManufactDate()),
                    StringUtils.getOrEmpty(h.getExpirateDate()), StringUtils.getOrEmpty(h.getMachineRoom()), StringUtils.getOrEmpty(h.getPurchaseDate())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbCommonDetailImportDto.class)
    ),
    /**
     * cmdb 设备（服务器）明细
     */
    CMDB_DEVICE_DETAIL(0, 0, "服务器明细.xlsx", getTitle(CmdbDeviceDetailImportDto.class),
            (ExportBuilder<List<CmdbDeviceDetailImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getSn()), StringUtils.getOrEmpty(h.getManufactDate()),
                    StringUtils.getOrEmpty(h.getExpirateDate()), StringUtils.getOrEmpty(h.getMachineRoom()), StringUtils.getOrEmpty(h.getPurchaseDate()),
                    StringUtils.getOrEmpty(h.getDeviceTypeName()), StringUtils.getOrEmpty(h.getInputPriceWithTax()), StringUtils.getOrEmpty(h.getInputPriceNoTax()),
                    StringUtils.getOrEmpty(h.getUser()), StringUtils.getOrEmpty(h.getDeviceStandardName())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbDeviceDetailImportDto.class)
    ),
    CMDB_DEVICE_SCRAP(0, 0, "服务器废弃.xlsx", getTitle(CmdbDeviceScrapImportDto.class),
            (ExportBuilder<List<CmdbDeviceScrapImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getSn())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, CmdbDeviceScrapImportDto.class)
    ),
    FORTRESS_NEW_MACHINE(0, 0, "堡垒机权限导出.xlsx", getTitle(FortressNewMachineImportDto.class),
            (ExportBuilder<List<CmdbCpuStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCore()),
                    StringUtils.getOrEmpty(h.getSmt())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, FortressNewMachineImportDto.class)
    ),
    FORTRESS_MACHINE(0, 0, "堡垒机权限.xlsx", getTitle(FortressMachineImportDto.class),
            (ExportBuilder<List<CmdbCpuStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCore()),
                    StringUtils.getOrEmpty(h.getSmt())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, FortressMachineImportDto.class)
    ),
    VPN_IMPORT(0, 0, "VPN导入.xlsx", getTitle(Vpn.class),
            (ExportBuilder<List<CmdbCpuStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCore()),
                    StringUtils.getOrEmpty(h.getSmt())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, Vpn.class)
    ),
    FORTRESS_ACCOUNT(0, 0, "堡垒机用户信息.xlsx", getTitle(FortressAccountImportDto.class),
            (ExportBuilder<List<CmdbCpuStandardImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getBrand()), StringUtils.getOrEmpty(h.getPartNum()),
                    StringUtils.getOrEmpty(h.getStandardNum()), StringUtils.getOrEmpty(h.getHz()), StringUtils.getOrEmpty(h.getCore()),
                    StringUtils.getOrEmpty(h.getSmt())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 1).read(0, 1, FortressAccountImportDto.class)
    ),
    FORTRESS_EXPORT(0, 0, "堡垒机用户权限.xlsx", getTitle(Fortress.class),
            (ExportBuilder<List<Fortress>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getAccount()), StringUtils.getOrEmpty(h.getMachine()), StringUtils.getOrEmpty(h.getAccountValidityFrom()),
                    StringUtils.getOrEmpty(h.getAccountValidityEnd()), StringUtils.getOrEmpty(h.getStatus()), StringUtils.getOrEmpty(h.getRole()), StringUtils.getOrEmpty(h.getDepartmentTwo()),
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getSystemName()), StringUtils.getOrEmpty(h.getPosition()), StringUtils.getOrEmpty(h.getRemark())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, FortressMachineImportDto.class)
    ),
    FORTRESS_NEW_EXPORT(0, 0, "堡垒机用户权限导出.xlsx", getTitle(FortressNew.class),
            (ExportBuilder<List<FortressNew>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getAccount()), StringUtils.getOrEmpty(h.getMachine()),StringUtils.getOrEmpty(h.getIp())
                    , StringUtils.getOrEmpty(h.getStatus()), StringUtils.getOrEmpty(h.getDepartmentTwo()),
                    StringUtils.getOrEmpty(h.getName()), StringUtils.getOrEmpty(h.getSystemName()), StringUtils.getOrEmpty(h.getPosition()), StringUtils.getOrEmpty(h.getRemark()),StringUtils.getOrEmpty(h.getOaStatus())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, FortressMachineImportDto.class)
    ),
    VPN_EXPORT(0, 0, "VPN用户权限导出.xlsx", getTitle(VpnExportDto.class),
            (ExportBuilder<List<Vpn>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getAccount()), StringUtils.getOrEmpty(h.getName()),StringUtils.getOrEmpty(h.getPathName()),StringUtils.getOrEmpty(h.getRemark())
                    , StringUtils.getOrEmpty(h.getResourceName()), StringUtils.getOrEmpty(h.getLastLoginTime()),
                     StringUtils.getOrEmpty(h.getOaStatus())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, VpnExportDto.class)
    ),
    VENDOR_IMPORT(0, 0, "供应商评价初始化预算数据.xlsx", getTitle(Fortress.class),
            (ExportBuilder<List<VendorImportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getRateOperatorName()), StringUtils.getOrEmpty(h.getVendorName()), StringUtils.getOrEmpty(h.getContractBeginDate()),
                    StringUtils.getOrEmpty(h.getContractEndDate()), StringUtils.getOrEmpty(h.getRateContent()), StringUtils.getOrEmpty(h.getContractContent()),
                    StringUtils.getOrEmpty(h.getApplyDate())
            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, VendorImportDto.class)
    ),
    VENDOR_EXPORT(0, 0, "信息技术服务机构评价.xlsx", getTitle(VendorExportDto.class),
            (ExportBuilder<List<VendorExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> Arrays.asList(
                    StringUtils.getOrEmpty(h.getDepartment()), StringUtils.getOrEmpty(h.getRateOperatorName()), StringUtils.getOrEmpty(h.getVendorName()),
                    StringUtils.getOrEmpty(h.getRateContent()), StringUtils.getOrEmpty(h.getProjectLevel()), StringUtils.getOrEmpty(h.getSummaryScore()),
                    StringUtils.getOrEmpty(h.getDefaultScore1()), StringUtils.getOrEmpty(h.getBelowScoreExplain1()), StringUtils.getOrEmpty(h.getDefaultScore2()), StringUtils.getOrEmpty(h.getBelowScoreExplain2()), StringUtils.getOrEmpty(h.getDefaultScore3()), StringUtils.getOrEmpty(h.getBelowScoreExplain3()),
                    StringUtils.getOrEmpty(h.getDefaultScore4()), StringUtils.getOrEmpty(h.getBelowScoreExplain4()), StringUtils.getOrEmpty(h.getDefaultScore5()), StringUtils.getOrEmpty(h.getBelowScoreExplain5()), StringUtils.getOrEmpty(h.getDefaultScore6()), StringUtils.getOrEmpty(h.getBelowScoreExplain6()),
                    StringUtils.getOrEmpty(h.getDefaultScore7()), StringUtils.getOrEmpty(h.getBelowScoreExplain7()), StringUtils.getOrEmpty(h.getDefaultScore8()), StringUtils.getOrEmpty(h.getBelowScoreExplain8()),
                    StringUtils.getOrEmpty(h.getPenaltyScore()), StringUtils.getOrEmpty(h.getPenaltyScoreExplain()),
                    StringUtils.getOrEmpty(h.getRateRemark()), StringUtils.getOrEmpty(h.getEvaluate()),StringUtils.getOrEmpty(h.getDeleteResason())

            )).collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, VendorExportDto.class)
    ),
    DEMAND_EXPORT(0, 0, "需求导出报表.xlsx", getTitle(DemandManagementExportDto.class),
            (ExportBuilder<List<DemandManagementExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> {
                Class<DemandManagementExportDto> clz = DemandManagementExportDto.class;
                return Arrays.stream(clz.getDeclaredFields())
                        .filter(f -> {
                            f.setAccessible(true);
                            return f.isAnnotationPresent(Alias.class);
                        })
                        .map(f -> {
                            try {
                                return Optional.ofNullable(f.get(h)).map(Object::toString).orElse(Strings.EMPTY);
                            } catch (IllegalAccessException e) {
                                return Strings.EMPTY;
                            }
                        })
                        .collect(Collectors.toList());
            })
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, DemandManagementExportDto.class)
    ),
    GITEE_WEEK_EXPORT(0, 0, "周报导出.xlsx", getTitle(IssueExportDto.class),
            (ExportBuilder<List<IssueExportDto>>) data -> Collections.isEmpty(data) ? new ArrayList<>(0)
                    : data.stream().map(h -> {
                Class<IssueExportDto> clz = IssueExportDto.class;
                return Arrays.stream(clz.getDeclaredFields())
                        .filter(f -> {
                            f.setAccessible(true);
                            return f.isAnnotationPresent(Alias.class);
                        })
                        .map(f -> {
                            try {
                                return Optional.ofNullable(f.get(h)).map(Object::toString).orElse(Strings.EMPTY);
                            } catch (IllegalAccessException e) {
                                return Strings.EMPTY;
                            }
                        })
                        .collect(Collectors.toList());
            })
                    .collect(Collectors.toList()),
            file -> ExcelUtil.getReader(file.getInputStream(), 0).read(0, 1, IssueExportDto.class)
    ),
    ;

    /**
     * 开始行
     */
    private final int beginRow;
    /**
     * 开始列
     */
    private final int beginCol;
    /**
     * 导出文件名
     */
    private final String fileName;
    /**
     * 表头
     */
    private final List<String> title;
    /**
     * 导出数据build方法
     */
    private final ExportBuilder exportBuilder;
    /**
     * 导入数据build方法
     */
    private final ReadImportBuilder readImportBuilder;

    /**
     * 通过反射获取类及父类中带有@Alias字段的value
     */
    private static List<String> getTitle(Class<?> clz) {
        List<Class<?>> clzList = new ArrayList<>();
        while (clz != null) {
            clzList.add(clz);
            clz = clz.getSuperclass();
        }
        List<String> title = new ArrayList<>();
        //倒序先将父节点的字段加入
        for (int i = clzList.size() - 1; i >= 0; i--) {
            clz = clzList.get(i);
            List<String> fields = Arrays.stream(clz.getDeclaredFields()).filter(f -> f.isAnnotationPresent(Alias.class)).map(f -> f.getAnnotation(Alias.class).value()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(fields)) {
                title.addAll(fields);
            }
        }
        return title;
    }

    /**
     * 构建导出数据
     */
    public <T> List<List<String>> export(T data) {
        return this.getExportBuilder().build(data);
    }

    /**
     * 读取导入数据
     */
    public <T> List<T> readImport(MultipartFile file) throws IOException {
        return this.getReadImportBuilder().read(file);
    }

    @FunctionalInterface
    private interface ExportBuilder<T> {
        List<List<String>> build(T data);
    }

    @FunctionalInterface
    private interface ReadImportBuilder<T> {
        List<T> read(MultipartFile file) throws IOException;
    }
}
